package core

import (
	"bytes"
	"encoding/json"
	"log"
	"strings"
)

type JSONBuilder struct {
}

func (builder *JSONBuilder) BuildHeadInfo(row []string, headFix [2]string) *HeadInfo {
	return buildLuaOrJson(row, headFix)
}

func (builder *JSONBuilder) GetSaveFileName(fileName string) string {
	if strings.HasSuffix(fileName, LuaFileNameFix) {
		return fileName
	} else {
		return fileName + LuaFileNameFix
	}
}

func (builder *JSONBuilder) BuildHeadLine(exportString *bytes.Buffer, saveFileName string, headInfo *HeadInfo) {
	idxName := headInfo.GetItemByType(LuaIdxName)
	if idxName != nil {
		exportString.WriteString("{")
	} else {
		exportString.WriteString("[")
	}
}
func (builder *JSONBuilder) BuildEnd(exportString *bytes.Buffer, headInfo *HeadInfo) {
	last := exportString.Len() - 1
	b := exportString.Bytes()[last]
	if byte(',') == b {
		exportString.Truncate(last)
	}
	exportString.WriteString("\n")
	item := headInfo.GetItemByType(LuaIdxName)
	if nil != item {
		exportString.WriteString("}")
	} else {
		exportString.WriteString("]")
	}

}
func (builder *JSONBuilder) GetID(row []string, headInfo *HeadInfo) string {
	idheadItem := headInfo.GetItemByType(LuaIdxName)
	if idheadItem != nil {
		return row[idheadItem.Ix]
	}
	return ""
}

func (builder *JSONBuilder) BuildLine(buffer *bytes.Buffer, info *HeadInfo, id string, row []string) {
	buffer.WriteString("\n")
	if "" != id {
		buffer.WriteString("\"")
		buffer.WriteString(id)
		buffer.WriteString("\":{")
	} else {
		buffer.WriteString("{")
	}

	var first = true
	for _, item := range info.Items {
		if item.Typ == LuaIdxName {
			continue
		}

		cellVal := row[item.Ix]
		if len(cellVal) == 0 {
			continue
		}
		if first {
			first = false
		} else {
			buffer.WriteString(",")
		}
		buffer.WriteString("\"")
		buffer.WriteString(item.FiledName)
		buffer.WriteString("\":")
		switch item.Typ {
		case "bool":
			parseBool(cellVal, buffer)
			break
		case "json":
			var m interface{}
			unmarshal := json.Unmarshal(bytes.NewBufferString(cellVal).Bytes(), &m)
			if unmarshal != nil {
				log.Fatal(unmarshal)
			} else {
				buffer.WriteString(cellVal)
			}
			break
		case "str", "fun":
			buffer.WriteString("\"")
			buffer.WriteString(cellVal)
			buffer.WriteString("\"")
			break
		case "num", "int":
			parseNum(cellVal, buffer)
			break
		case "nums":
			buffer.WriteString("[")
			buffer.WriteString(cellVal[1 : len(cellVal)-1])
			buffer.WriteString("]")
			break
		case "strs":
			content := cellVal[1 : len(cellVal)-1]
			split := strings.Split(content, ",")
			buffer.WriteString("[")
			var first = true
			for _, v := range split {
				if first {
					first = false
				} else {
					buffer.WriteString(",")
				}
				buffer.WriteString("\"")
				buffer.WriteString(v)
				buffer.WriteString("\"")
			}
			buffer.WriteString("]")
			break
		default:
			buffer.WriteString(cellVal)
		}
	}
	buffer.WriteString("},")
}
